package com.app.twth.base;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.device.ScanManager;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.android.decode.BarcodeManager;
import com.android.decode.DecodeResult;
import com.android.decode.ReadListener;
import com.app.twth.app.AppRouter;
import com.app.twth.app.Constant;
import com.app.twth.databinding.ActivityBaseBinding;
import com.app.twth.databinding.BottomLayoutBinding;
import com.app.twth.databinding.TitlebarBinding;
import com.app.twth.scan.IDataScan;
import com.app.twth.statusbar.ScreenUtils;
import com.app.twth.statusbar.StatusBarUtil;
import com.app.twth.utils.EditTextUtil;
import com.app.twth.utils.Loading;
import com.app.twth.utils.PermissionChecker;
import com.app.twth.utils.Utils;
import com.google.zxing.activity.CaptureActivity;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * ****************************************************************
 * 文件名称: BaseActivity
 * 文件描述:
 * 注意事项:
 * 版权声明:
 * ****************************************************************
 */
public abstract class BaseActivity<VB extends ViewDataBinding, VM extends BaseAndroidViewModel> extends AppCompatActivity implements ReadListener {
    private String TAG = getClass().getSimpleName();
    protected BaseActivity mContext;
    public final static String SCAN_ACTION = "urovo.rcv.message";//扫描结束action
    Loading dialog;
    ActivityBaseBinding baseBinding;
    TitlebarBinding titlebarBinding;
    public BottomLayoutBinding bottomLayoutBinding;

    public long timeMillis;
    public long spaceTime = 1000;
    public boolean isFinish = true;
    public int width, height, soundid;
    public SoundPool soundpool = null;
    //优博讯
    public ScanManager mScanManager;
    public Vibrator mVibrator;

    //MoByData
    private BarcodeManager mBarcodeManager;

    public String barcodeStr;
    private IDataScan mIDataScan;

    public VB binding;
    public VM viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        baseBinding = ActivityBaseBinding.inflate(getLayoutInflater());
        titlebarBinding = TitlebarBinding.bind(baseBinding.baseTop.getRoot());
        bottomLayoutBinding = BottomLayoutBinding.bind(baseBinding.baseBottom.getRoot());

        View rootView = baseBinding.getRoot();
        setContentView(rootView);

        Type type = this.getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            try {
                Class<VB> clazz = (Class<VB>) ((ParameterizedType) type).getActualTypeArguments()[0];
                Method method = clazz.getMethod("inflate", LayoutInflater.class);
                binding = (VB) method.invoke(null, getLayoutInflater());
            } catch (Exception e) {
                e.printStackTrace();
            }
            assert binding != null;
//            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//            setContentView(binding.getRoot());
            baseBinding.framelayout.addView(binding.getRoot());
        }
        if (viewModel == null) {
            Class modelClass;
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = BaseViewModel.class;
            }
            viewModel = (VM) createViewModel(modelClass);
        }
        binding.setVariable(initViewModelId(), viewModel);

        ScreenUtils.setStatusBarTransparentAndWordsGray(getWindow());
        StatusBarUtil.setStatusBarLightMode(this, Color.WHITE);

        titlebarBinding.ivBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isFinish) {
                    finish();
                } else {
                    setBack();
                }
            }
        });
        titlebarBinding.tvTitle.setText(setTitle());
        Display display = getWindowManager().getDefaultDisplay();
        width = display.getWidth();
        height = display.getHeight();

        //初始化数据
        initData();
        //事件监听
        initListener();
        //页面事件监听的方法，一般用于ViewModel层转到View层的事件注册
        initViewObservable();
        mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

//        viewModel.errorResultCode.observe(this, code -> {
//            showHint((String) code);
//        });
//        viewModel.isLoading.observe(this, b -> {
//            if (b instanceof LoadingBean) {
//                LoadingBean loadingBean = (LoadingBean) b;
//                if (loadingBean.isShow()) {
//                    showProgressDialog(loadingBean.getMsg());
//                } else {
//                    dismissProgressDialog();
//                }
//            }
//
//        });
    }

    //设置初始化viewmodelid
    protected abstract int initViewModelId();

    /**
     * 创建ViewModel
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T extends AndroidViewModel> T createViewModel(Class<T> cls) {
        return new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(mContext.getApplication())).get(cls);
    }

    protected abstract void initData();

    protected abstract void initListener();


    protected void initViewObservable() {
    }

    protected abstract String setTitle();

    public void setBack() {
    }

    public void setTitle(String title) {
        titlebarBinding.tvTitle.setText(title);
    }

    public void setRight(String title) {
        titlebarBinding.tvRight.setText(title);
        titlebarBinding.tvRight.setVisibility(View.VISIBLE);
    }

    public void setRightGone() {
        titlebarBinding.tvRight.setVisibility(View.GONE);
    }

    public void setReset(String title) {
        bottomLayoutBinding.tvReset.setText(title);
        bottomLayoutBinding.tvReset.setVisibility(View.VISIBLE);
    }

    public void setResetGone() {
        bottomLayoutBinding.tvReset.setVisibility(View.GONE);
    }

    public void setNext(String text) {
        if (!Utils.isEmpty(text)) {
            bottomLayoutBinding.tvNext.setText(text);
        }
        bottomLayoutBinding.tvNext.setVisibility(View.VISIBLE);
    }

    public void setNextGone() {
        bottomLayoutBinding.tvNext.setVisibility(View.GONE);
    }

    public void setBackGone() {
        titlebarBinding.ivBack.setVisibility(View.GONE);
    }

    public void setLayoutBottomGone() {
        bottomLayoutBinding.baseLayoutBottom.setVisibility(View.GONE);
    }

    public void setLayoutBottomContentGone() {
        bottomLayoutBinding.baseLayoutBottomContent.setVisibility(View.GONE);
    }

    public void showHint(String text) {
        bottomLayoutBinding.tvHint.setText(Utils.getStr(text));
    }

    public void initScan() {
        Log.e(TAG, "Build.MANUFACTURER:" + Build.MANUFACTURER);
        if (Build.MANUFACTURER.contains("Urovo")) {
            try {
                mScanManager = new ScanManager();
                mScanManager.openScanner();
                mScanManager.switchOutputMode(0);
                soundpool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 100); // MODE_RINGTONE
                soundid = soundpool.load("/etc/Scan_new.ogg", 1);
                Log.e(TAG, "openScanner");
            } catch (Exception e) {
                e.printStackTrace();
            }

            IntentFilter filter = new IntentFilter();
            filter.addAction(SCAN_ACTION);
            filter.addAction("android.intent.ACTION_DECODE_DATA");
            registerReceiver(mScanReceiver, filter);
            Log.e(TAG, "registerReceiver:" + Build.MANUFACTURER);
        } else if (Build.MANUFACTURER.contains("Moby")) {
            initMoByData();
        } else {
            try {
                mIDataScan = new IDataScan();
                mIDataScan.initScan(this, new IDataScan.OnScanListener() {
                    @Override
                    public void scanSuccess(String code) {
                        //解码成功
                        Log.e(TAG, "=======解码成功==gg====" + code);
                        barcodeStr = code;
                        if (Utils.isEmpty(barcodeStr)) {
                            return;
                        }
                        baseHandler.sendEmptyMessage(1);
                    }

                    @Override
                    public void scanFailed(String message) {
                        //解码失败
                        Log.e(TAG, "=======解码失败==gg====" + message);
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //初始化MoByData
    private void initMoByData() {
        try {
            mBarcodeManager = new BarcodeManager();

            //设置扫码结果后缀为空
            Intent mSendIntent;
            mSendIntent = new Intent("com.android.action.setPropertyString");
            mSendIntent.putExtra("PropertyID", 0x0027);
            // 广播action地址改成 com.barcode.sendBroadcast
            mSendIntent.putExtra("PropertyString", "");
            sendBroadcast(mSendIntent);

            mBarcodeManager.isInitialized();
            mBarcodeManager.addReadListener(this);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void unScan() {
        try {
            Log.e(TAG, "unScan");
            if (mScanManager != null) {
                mScanManager.switchOutputMode(1);
                mScanManager.stopDecode();
            }
            if (mScanReceiver != null) {
                unregisterReceiver(mScanReceiver);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            if (mBarcodeManager != null) {
                mBarcodeManager.stopDecode();
                mBarcodeManager.removeReadListener(this);
                mBarcodeManager.release();
                mBarcodeManager = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            if (mIDataScan != null) {
                mIDataScan.destroy();
                mIDataScan = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setScan() {
        Log.e("BaseActivity", "setScan()");
        // 验证相机权限
        if (PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA)) {
            //这个说明系统版本在6.0之下，不需要动态获取权限。
            AppRouter.showActivityForResult(this, CaptureActivity.class, null, Constant.SCANNIN_GREQUEST_CODE);
        } else {
            PermissionChecker.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA}, Constant.APPLY_CAMERA_PERMISSIONS_CODE);
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.e(">>>>", "dispatchTouchEvent:");
        //获取当前获得焦点的View
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            View view = getCurrentFocus();
            //调用方法判断是否需要隐藏键盘
            EditTextUtil.hideInput(mContext);
        }
        return super.dispatchTouchEvent(ev);
    }


    protected void showProgressDialog(String content) {
        if (dialog != null) {
            dialog.dismiss();
        }
        if (dialog == null) {
            if (Utils.isEmpty(content)) {
                dialog = Loading.newLoading(mContext);
            } else {
                dialog = Loading.newLoading(mContext, content);
            }
        }
        dialog.show();
    }

    protected void dismissProgressDialog() {
        if (dialog != null) {
            dialog.dismiss();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == Constant.SCANNIN_GREQUEST_CODE) {                //扫一扫处理
            if (data == null) {
                return;
            }
            try {
                // 显示扫描到的内容
                barcodeStr = data.getStringExtra(CaptureActivity.SCAN_QRCODE_RESULT);
                if (Utils.isEmpty(barcodeStr)) {
                    return;
                }
                barcodeStr = barcodeStr.trim();
                if (Utils.isEmpty(barcodeStr)) {
                    return;
                }
                baseHandler.sendEmptyMessage(1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    Handler baseHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            getScanninCode();
        }
    };
    public BroadcastReceiver mScanReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            byte[] barcode = intent.getByteArrayExtra(ScanManager.DECODE_DATA_TAG);
            Log.e(TAG, "barcodeStr1111111:");
            if (barcode == null) {
                return;
            }
            int barocodelen = intent.getIntExtra("length", 0);
            if (barcode.length < barocodelen) {
                barocodelen = barcode.length;
            }
            barcodeStr = new String(barcode, 0, barocodelen);
            Log.e(TAG, "barcodeStr:" + barcodeStr);
            if (Utils.isEmpty(barcodeStr)) {
                return;
            }
            barcodeStr = barcodeStr.trim();
            if (Utils.isEmpty(barcodeStr)) {
                return;
            }
            if (System.currentTimeMillis() - timeMillis < spaceTime) {//1000毫秒内触发一次
                return;
            }
            timeMillis = System.currentTimeMillis();

            soundpool.play(soundid, 1, 1, 0, 0, 1);
            mVibrator.vibrate(100);

            getScanninCode();
        }
    };

    public void getScanninCode() {
    }

    //MoByData扫码回调
    @Override
    public void onRead(DecodeResult decodeResult) {
        String replace = decodeResult.getText().replace("\n", "");
        Log.e(TAG, "replace:" + replace);
//        JSONObject object = new JSONObject();
//        object.put("result", decodeResult.getText().replace("\n", ""));
//        callback.invokeAndKeepAlive(object);
    }
}
